package com.adjy.pathbuilders.rendering.loading;

import java.io.IOException;
import java.util.HashMap;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;

import com.adjy.pathbuilders.objects.GameEntityType;
import com.adjy.pathbuilders.physics.PhysicalWorld;
import com.adjy.pathbuilders.rendering.Animation;
import com.adjy.pathbuilders.rendering.AnimationPack;
import com.adjy.pathbuilders.rendering.DisplayConverter;
import com.adjy.pathbuilders.rendering.Point;

@SuppressLint("NewApi")
public class AnimationFactory extends ImageFactory {

	private final static String ANIMATIONS_FILE = "animations_file";
	private final static String ANIMATIONS_TYPE_FILE = "animation_type_file";

	private HashMap<GameEntityType, AnimationPack> loadedAnimations;

	public AnimationFactory(Context c) {
		super(c);
	}

	public AnimationPack getAnimationsFor(GameEntityType type) {
		if (loadedAnimations.containsKey(type)) {
			return loadedAnimations.get(type).copy();
		}
		return null;
	}

	
	public void releaseAnimations() {
		for (GameEntityType type : loadedAnimations.keySet())
			loadedAnimations.get(type).release();
		
		loadedAnimations.clear();
	}

	/*
	 * Loading Methods
	 */

	public void loadAnimations() {

		// Loading Stuff
		try {
			HashMap<String, AnimationDescription> animationsDesc = ImageFileParser
					.parseAnimationFile(getContext().getAssets().open(
							ANIMATIONS_FILE));

			HashMap<GameEntityType, String[]> entityAnimations = ImageFileParser
					.parseAnimationsTypeFile(getContext().getAssets().open(
							ANIMATIONS_TYPE_FILE));

			// TODO : Refactor


			// Load Animations
			loadedAnimations = new HashMap<GameEntityType, AnimationPack>();

			// Set Source Screen to Physics World
			DisplayConverter.setPhysicsSize(PhysicalWorld.MAXIMUM_WIDTH, PhysicalWorld.MAXIMUM_HEIGHT);

			for (GameEntityType type : entityAnimations.keySet()) {

				HashMap<String, Animation> animations = new HashMap<String, Animation>();

				for (String animationName : entityAnimations.get(type)) {

					// Load Animation
					float[] size = GameEntityType.getSizeFor(type);
					Animation a = loadScaledAnimation(animationsDesc.get(animationName), size[0], size[1]);
					animations.put(animationName, a);

				}

				loadedAnimations.put(type, new AnimationPack(animations));
			}

		} catch (Exception e) {
			Log.e("LoadAnimations", e.getLocalizedMessage());
			e.printStackTrace();
		}
	}
	private Bitmap loadKeyFrame(String path, float width, float height, boolean pixelSizes) throws IOException {
		BitmapFactory.Options options = new BitmapFactory.Options();
		
		if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.HONEYCOMB_MR2) {
		     // newer versions after HONEYCOMB
			options.inPreferredConfig = Bitmap.Config.ARGB_8888;
		} else {
			// Honeycomb and lower versions
			options.inPreferredConfig = Bitmap.Config.ARGB_4444;
		}
		
		Bitmap b = BitmapFactory.decodeStream(getContext().getAssets().open(path), null, options);
		if (width >= 0 && height >= 0) {

			if (!pixelSizes) {
				Point point = DisplayConverter.convertFromPhysics(width, height);
				width =  point.getX();
				height = point.getY();
			}
			
			Bitmap scaled = Bitmap.createScaledBitmap(b, (int) width, (int) height, true);
			b.recycle();
			return scaled;
		}

		return b;
	}

	private Animation loadScaledAnimation(AnimationDescription ad, float width, float height) throws IOException {
		Animation a;

		Bitmap[] keyFrames = new Bitmap[ad.getKeyFrames().length];
		for (int i = 0 ; i < keyFrames.length ; i++)
			keyFrames[i] = loadKeyFrame(ad.getKeyFrames()[i], width, height, false);

		a = new Animation(ad.getID(), keyFrames, ad.getDurations());
		return a;
	}
}
